package com.jd.finance.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jd.finance.core.mapper.*;
import com.jd.finance.core.pojo.dto.AllAuditorDTO;
import com.jd.finance.core.pojo.entity.*;
import com.jd.finance.core.service.OpreateLogService;
import com.jd.finance.core.service.UserService;
import com.jd.finance.result.BaseResult;
import com.jd.finance.util.IpUtil;
import com.jd.finance.util.JwtUtils;
import com.jd.finance.util.MD5;
import com.jd.finance.util.RegexValidateUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author LiQingBo
 * @since 2022-05-17
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private CompanyMapper companyMapper;
    @Resource
    private AdminUtilsServiceImpl adminUtilsService;
    @Resource
    private OpreateLogService opreateLogService;
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private AssignMapper assignMapper;

    /**
     * 注册
     *
     * @param userAccount   账号
     * @param userPassword  密码
     * @param checkPassword 确认密码
     * @return
     */
    @Override
    @Transactional
    public BaseResult userRegister(String userAccount, String userPassword, String checkPassword) {
        if (StringUtils.isAllBlank(userAccount, userPassword, checkPassword)) {
            log.error("注册信息为空！");
            return BaseResult.error().message("注册信息为空");
        }
        //账号不能少于四位
        if (userAccount.length() < 4) {
            return BaseResult.error().message("账号不能少于四位");
        }
        //密码长度不能少于8位
        if (userPassword.length() < 8 || checkPassword.length() < 8) {
            return BaseResult.error().message("密码长度不能少于8位");

        }
        //两次密码不一致
        if (!userPassword.equals(checkPassword)) {
            return BaseResult.error().message("两次密码不一致");
        }
        //判断账户是否已被注册
        QueryWrapper<User> query = new QueryWrapper();
        query.eq("user_account", userAccount);
        long count = this.count(query);
        if (count > 0) {
            return BaseResult.error().message("账户已被注册");
        }
        //判断账户不能包含特殊字符
        String validPattern = "[`~!@#$%^&*()+=|{}':;',\\\\[\\\\].<>/?~!@#￥%……&*（）——+|{}【】’；：“”‘。，、？]";
        Matcher matcher = Pattern.compile(validPattern).matcher(userAccount);
        if (matcher.find()) {
            return BaseResult.error().message("账户不能包含特殊字符");
        }
        //MD5加密
        String password = MD5.encrypt(userPassword);

        //插入数据库
        User user = new User();
        user.setUserAccount(userAccount);
        user.setUserPassword(password);
        int inster = userMapper.insert(user);

        //查询用户id
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.lambda().eq(User::getUserAccount, userAccount);
        User user1 = userMapper.selectOne(qw);
        //查询权限id
        QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();
        roleQueryWrapper.lambda().eq(Role::getRoleName,"用户");
        Role role = roleMapper.selectOne(roleQueryWrapper);

        //创建中间表数据
        Assign assign = new Assign();
        assign.setUid(user1.getUid());
        assign.setRoleId(role.getRoleId());
        //插入中间表
        int insert1 = assignMapper.insert(assign);

        if (insert1 == 0 && inster == 0) {
            return BaseResult.error().message("保存失败");
        }
        Map<String, Object> result = new HashMap<>();
        result.put("zhuceJieguo", 1);
        return BaseResult.ok().data(result);
    }

    /**
     * 用户登录
     * @param userAccount
     * @param userPassword
     * @param request
     * @return
     */
    @Override
    public BaseResult userLogin(String userAccount, String userPassword, HttpServletRequest request) {
        String password = MD5.encrypt(userPassword);
        //查询
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("user_account", userAccount)
                .eq("user_password", password);
        return getBaseResult(qw,request);
    }

    /**
     * 个人实名认证
     *
     * @param idNo
     * @param userName
     * @param userPhone
     * @param uId
     * @return
     */
    @Override
    public BaseResult userCertifica(String idNo, String userName, String userPhone, Integer uId) {
        if (StringUtils.isAllBlank(idNo, userName, userPhone, String.valueOf(uId))) {
            log.error("提交信息不能为空！");
            return BaseResult.error().message("提交信息不能为空");
        }
        //验证身份是否存在
        QueryWrapper<User> query = new QueryWrapper();
        query.eq("id_NO", idNo);
        long count = this.count(query);
        if (count > 0) {
            log.error("账户已实名认证");
            return BaseResult.error().message("账户已实名认证");
        }
        //验证身份证号
        if (!RegexValidateUtils.checkIdNo(idNo)) {
            log.error("身份证号输入不正确");
            return BaseResult.error().message("身份证号输入不正确");
        }
        //验证手机号
        if (!RegexValidateUtils.checkCellphone(userPhone)) {
            log.error("手机号输入不正确");
            return BaseResult.error().message("手机号输入不正确");
        }
        //插入数据库
        User user = new User();
        user.setIdNo(idNo);
        user.setUserName(userName);
        user.setUserPhone(userPhone);
        user.setUid(uId);
        int i = userMapper.updateById(user);
        if (i == 0) {
            return BaseResult.ok().data("zhuceJieguo", 0);
        }
        return BaseResult.ok().data("zhuceJieguo", 1);
    }

    /**
     * 查询个人是否实名认证
     *
     * @param uid 用户id
     * @return
     */
    @Override
    public BaseResult getUserCertifica(Integer uid) {
        if (uid == null) {
            log.error("用户id为空!");
            return BaseResult.error().message("用户id为空!");
        }
        User user = userMapper.selectById(uid);
        if (user == null) {
            log.error("用户未注册");
            return BaseResult.error().message("用户未注册");
        }
        if (StringUtils.isBlank(user.getIdNo())) {
            return BaseResult.error().message("用户未认证").data("cxjieguo", 0);
        }
        return BaseResult.ok().data("cxjieguo", 1);
    }

    /**
     * 查询个人信息
     *
     * @param uid
     * @return
     */
    @Override
    public BaseResult getUserInfo(Integer uid) {

        if (StringUtils.isBlank(String.valueOf(uid))) {
            log.error("用户信息id为空");
            return BaseResult.error().message("用户信息id为空");
        }
        //根据uid进行查询
        User user1 = userMapper.selectById(uid);
        //返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("uid", user1.getUid());
        result.put("grname", user1.getUserName());
        result.put("grphone", user1.getUserPhone());

        return BaseResult.ok().data(result);
    }

    /**
     * 修改密码，联系电话
     *
     * @param uid          用户id
     * @param userPassword 用户密码
     * @param userPhone    用户手机号
     * @return
     */
    @Override
    public BaseResult updateInfo(Integer uid, String userPassword, String userPhone) {

        //密码长度不能少于8位
        if (userPassword.length() < 8) {
            log.error("密码长度不能少于8位");
            return BaseResult.error().message("密码长度不能少于8位");
        }
        //处理传入数据
        String MD5password = MD5.encrypt(userPassword);
        User user = new User();
        user.setUid(uid);
        if (StringUtils.isNotBlank(userPassword)) {
            user.setUserPassword(MD5password);
        }
        if (StringUtils.isNotBlank(userPhone)) {
            user.setUserPhone(userPhone);
        }
        int i = userMapper.updateById(user);
        return BaseResult.ok().data("xiugaiResult", i);
    }

    /**
     * 查询平台累计注册数量
     *
     * @return
     */
    @Override
    public BaseResult getUserCount() {
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.select("uid");
        int count = userMapper.selectCount(qw);
        if (count == 0) {
            return BaseResult.error().message("未查询到累计注册人数！");
        }
        return BaseResult.ok().data("jiaoyiRegister", count);
    }

    /**
     * 后台用户登录
     * @param userPassword  密码
     * @param userPhone 账户
     * @param request
     * @return
     */
    @Override
    public BaseResult userAdminLogin(String userPassword, String userPhone, HttpServletRequest request) {
        String password = MD5.encrypt(userPassword);
        //查询
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("user_account", userPhone)
                .eq("user_password", password);
        return getBaseResult(qw,request);
    }

    /**
     * 根据uid进行修改密码，手机号
     *
     * @param uid          用户id
     * @param userPhone    用户手机号
     * @param userPassword 用户密码
     * @param adminId      管理员id
     * @return 是否修改成功
     */
    @Override
    public BaseResult updateUserInfo(Integer uid, String userPhone,
                                     String userPassword, Integer adminId) {
        if (uid == null && adminId == null) {
            log.error("修改用户信息错误 S");
            return BaseResult.error().message("修改用户信息错误 S");
        }
        if (StringUtils.isAllBlank(userPassword, userPhone)) {
            log.error("修改用户信息错误！S");
            return BaseResult.error().message("修改用户信息错误S");
        }
        /**
         *  判断是否为管理员
         */
        if (isAdmin(adminId)) {
            log.error("当前登录用户不是管理员账户 S");
            return BaseResult.error().message("当前登录用户不是管理员账户 S");
        }
        //密码加密处理
        String MD5password = MD5.encrypt(userPassword);
        User user = new User();
        user.setUid(uid);
        user.setUserPassword(MD5password);
        user.setUserPhone(userPhone);

        int update = userMapper.updateById(user);
        return BaseResult.ok().data("xglnf", update);
    }

    /**
     * 查询 uid 查询 个人信息
     *
     * @param uid
     * @return
     */
    @Override
    public User getUserInfoS(Integer uid) {
        User user = userMapper.selectById(uid);
        if (user == null) {
            log.error("未查询到用户相关信息");
        }

        return user;
    }

    /**
     * 根据uid查询还款记录
     *
     * @param uid
     * @return
     */
    @Override
    public User getRepayInfo(Integer uid) {
        User user = userMapper.selectById(uid);
        if (user == null) {
            log.error("未查询到用户的还款记录");
        }
        return user;
    }

    /**
     * 获取前台账号总数
     *
     * @param uid
     * @return
     */
    @Override
    public BaseResult getSumAccount(Integer uid) {
        QueryWrapper qw = new QueryWrapper<>();
        qw.ne("is_admin", 0);
        Integer count = userMapper.selectCount(qw);
        return BaseResult.ok().data("qiantaizhanghaonumber:", count);
    }

    /**
     * 获取 所有审核员信息
     *
     * @param uid
     * @return
     */
    @Override
    public BaseResult getAllAuditor(Integer uid) {
        if (uid == null) {
            log.error("管理员信息为空!");
            return BaseResult.error().message("管理员信息为空!");
        }
        List<AllAuditorDTO> list = userMapper.getAllAuditor();
        if (list == null && list.size() == 0) {
            log.error("未查询到审核员信息!");
            return BaseResult.error().message("未查询到审核员信息!");
        }
        return BaseResult.ok().data("auditorList", list);
    }


    /**
     * 登录公用方法
     *
     * @param qw 查询条件
     * @return
     */
    private BaseResult getBaseResult(QueryWrapper<User> qw, HttpServletRequest request) {
        List<User> users = userMapper.selectList(qw);
        List<String> role = userMapper.findRole(users.get(0).getUid());

        if (users == null || users.size() == 0) {
            return BaseResult.error().message("用户名或密码错误");
        }
        opreateLogService.add(users.get(0).getUid(),"前台用户登录","登录",IpUtil.getIpAddr(request));
        String token = JwtUtils.createToken(Integer.toUnsignedLong(users.get(0).getUid()),
                users.get(0).getUserAccount(), role);
        Map<String, Object> result = new HashMap<>();
        result.put("userId", users.get(0).getUid());
        result.put("userName", users.get(0).getUserName());
        result.put("token",token);
        return BaseResult.ok().data(result);
    }

    /**
     * 判断是否是 管理员角色
     *
     * @param admin 管理员id
     * @return ture 是 / false 不是
     */
    public boolean isAdmin(Integer admin) {
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("uid", admin);
        User user = userMapper.selectOne(qw);
        return user.getAdmin();
    }

    /**
     * 根据银行信贷员uid，查询所属银行信息
     *
     * @param uid
     * @return
     */
    @Override
    public BaseResult getBelongBankInfo(Integer uid) {
        if (uid == null) {
            log.error("传入参数为空S");
            return BaseResult.error().message("传入参数为空");
        }
        if (!adminUtilsService.isBank(uid)) {
            log.error("该用户不是银行信贷员S");
            return BaseResult.error().message("该用户不是银行信贷员");
        }
        Bank bankInfo = userMapper.getBelongBankInfo(uid);
        Map<String, Object> result = new HashMap<>();
        result.put("bankname", bankInfo.getBankName());
        result.put("bankdz", bankInfo.getBankAddress());

        return BaseResult.ok().data(result);
    }

    /**
     * 根据uid，修改密码
     *
     * @param uid           用户(管理员)id
     * @param oldPassword   旧密码
     * @param newPassword   新密码
     * @param checkPassword 确认密码
     * @param request       servlet请求
     * @return
     */
    @Override
    public BaseResult updatePassword(Integer uid, String oldPassword, String newPassword, String checkPassword, HttpServletRequest request) {
        if (StringUtils.isAllBlank(String.valueOf(uid),oldPassword,newPassword,checkPassword)) {
            log.error("根据uid修改密码，提交信息为空!");
            return BaseResult.error().message("根据uid修改密码，提交信息为空!");
        }

        if (!adminUtilsService.isAdmin(uid)) {
            log.error("该用户非管理员身份!");
            return BaseResult.error().message("根据uid修改密码该用户非管理员身份!");
        }


        //新密码不能少于八位
        if (newPassword.length()<8) {
            log.error("密码不能少于八位!");
            return BaseResult.error().message("密码不能少于八位!");
        }

        //判断两次密码是否一致
        if (!newPassword.equals(checkPassword)) {
            log.error("两次密码不一致!");
            return BaseResult.error().message("两次密码不一致!");
        }
        String oldPass=MD5.encrypt(oldPassword);
        String newPass=MD5.encrypt(newPassword);
        UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
        User user=new User();
        user.setUserPassword(newPass);
        userUpdateWrapper.eq("uid",uid)
                .eq("user_password",oldPass);
        int update=userMapper.update(user,userUpdateWrapper);
        if (update < 1) {
            log.error("修改失败!");
            return BaseResult.ok().data("xiugaijieguo",0).message("修改失败!");
        }

        boolean add= opreateLogService.add(uid,"修改","根据uid修改密码", IpUtil.getIpAddr(request));
        if (!add) {
            log.error("根据uid修改密码，添加操作日志失败！");
        }
        return BaseResult.ok().data("xiugaijieguo",1).message("修改成功!");
    }

    /**
     * 根据uid，修改手机号
     * @param uid       用户id
     * @param userPhone 用户手机号
     * @param request   servlet请求
     * @return
     */
    @Override
    public BaseResult updatePhone(Integer uid, String userPhone, HttpServletRequest request) {
        if (uid==null || userPhone==null) {
            log.error("根据uid修改手机号，提交信息为空!");
            return BaseResult.error().message("根据uid修改手机号，提交信息为空!");
        }
        if (!adminUtilsService.isAdmin(uid)) {
            log.error("该用户非管理员身份!");
            return BaseResult.error().message("根据uid修改密码该用户非管理员身份!");
        }

        //判断手机号格式
        boolean phone=RegexValidateUtils.checkCellphone(userPhone);
        if (!phone) {
            log.error("用户输入的手机号格式不正确!");
            return BaseResult.error().message("用户输入的手机号格式不正确!");
        }

        //判断手机号是否已被使用
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("user_phone",userPhone);
        User user1=userMapper.selectOne(userQueryWrapper);
        if (user1!=null) {
            log.error("该手机号已被使用!");
            return BaseResult.error().message("该手机号已被使用!");
        }

        UpdateWrapper<User> userUpdateWrapper=new UpdateWrapper<>();
        User user=new User();
        user.setUserPhone(userPhone);
        userUpdateWrapper.eq("uid",uid);
        int update=userMapper.update(user,userUpdateWrapper);

        if (update < 1) {
            log.error("修改失败!");
            return BaseResult.ok().data("xiugaijieguo",0).message("修改失败!");
        }

        boolean add= opreateLogService.add(uid,"修改","根据uid修改密码", IpUtil.getIpAddr(request));
        if (!add) {
            log.error("根据uid修改密码，添加操作日志失败!");
        }
        return BaseResult.ok().data("xiugaijieguo",1).message("修改成功!");
    }

    /**
     * 根据uid删除用户表
     * @param uid
     * @param leaveId
     * @param request
     * @return
     */
    @Override
    public BaseResult deleteUserTableById(Integer uid, Integer leaveId, HttpServletRequest request) {
        if(uid == null){
            log.error("uid为空");
            return BaseResult.error().message("uid为空");
        }
        if(leaveId == null){
            log.error("离职人员id为空");
            return BaseResult.error().message("离职人员id为空");
        }
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("uid",leaveId);

        User user = new User();
        user.setUid(leaveId);
        int i = userMapper.delete(qw);
        if (i < 1) {
            log.error("删除失败!");
            return BaseResult.ok().data("xiugaijieguo",0).message("删除失败!");
        }

        boolean add= opreateLogService.add(uid,"删除","根据uid删除用户表", IpUtil.getIpAddr(request));
        if (!add) {
            log.error("根据uid修改密码，添加操作日志失败!");
        }
        return BaseResult.ok().data("shanchujieguo:",i);
    }

    /**
     * 根据手机号或者姓名查询后台用户信息
     * @param uid
     * @param userInfo
     * @return
     */
    @Override
    public BaseResult getAdminAccountInfo(Integer uid, String userInfo) {
        if(uid == null){
            log.error("uid为空");
            return BaseResult.error().message("uid为空");
        }
        if(userInfo == null){
            log.error("输入信息为空");
            return BaseResult.error().message("输入信息为空");
        }
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.and(t->t.like("user_phone",userInfo).or().like("user_name",userInfo));
        List<User> users = userMapper.selectList(qw);
        return BaseResult.ok().data("users:",users);
    }

    /**
     * 扫码登录
     * @param uid  用户id
     * @return
     */
    @Override
    public BaseResult scanCode(Integer uid) {
        if (uid==null) {
            log.error("扫码登录，uid为空!");
            return BaseResult.error().message("扫码登录，uid为空!");
        }

        User user=userMapper.selectById(uid);

        if (user==null) {
            log.error("该用户不存在!");
            return BaseResult.error().message("该用户不存在!");
        }

        Map<String,Object> result=new HashMap<>();
        result.put("userid",uid);
        result.put("userName",user.getUserName());
        return BaseResult.ok().data(result);
    }


    /**
     * 查询所有后台用户信息
     * @param uid
     * @return
     */
    @Override
    public BaseResult getAllAdminInfo(Integer uid) {
        if (uid == null){
            log.error("id为空");
            return BaseResult.error().message("用户id为空");
        }

        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("is_admin",1);
        List<User> users = userMapper.selectList(qw);
        return BaseResult.ok().data("users",users);

    }



}